﻿using System;
using System.ComponentModel;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using CommonExtensions.IDataErrorInfoExtensions.Testing;
using Xunit;

namespace CommonExtensions.Tests
{
    public class IDataErrorInfoExtensionsTests
    {
        [Fact]
        public void AssertPropertyValidShouldThrowIfNull()
        {
            TestObject obj = null;
            Assert.Throws<ArgumentNullException>(() => obj.AssertPropertyValid(o => o.ValidPropertyNull));
        }

        [Fact]
        public void AssertPropertyValidShouldThrowIfPropertyExpressionNull()
        {
            Assert.Throws<ArgumentNullException>(() => new TestObject().AssertPropertyValid(null));
        }

        [Fact]
        public void AssertPropertyValidShouldThrowIfPropertyHasErrors()
        {
            Assert.Throws<AssertFailedException>(() => new TestObject().AssertPropertyValid(o => o.InvalidProperty));
        }

        [Fact]
        public void AssertPropertyValidShouldNotThrowIfPropertyErrorsReturnNull()
        {
            Assert.DoesNotThrow(() => new TestObject().AssertPropertyValid(o => o.ValidPropertyNull));
        }

        [Fact]
        public void AssertPropertyValidShouldNotThrowIfPropertyErrorsReturnBlank()
        {
           Assert.DoesNotThrow(() => new TestObject().AssertPropertyValid(o => o.ValidPropertyBlank));
        }

        [Fact]
        public void AssertPropertyInvalidShouldThrowIfNull()
        {
            TestObject obj = null;
            Assert.Throws<ArgumentNullException>(() => obj.AssertPropertyInvalid(o => o.InvalidProperty));
        }

        [Fact]
        public void AssertPropertyInvalidShouldThrowIfPropertyExpressionNull()
        {
            Assert.Throws<ArgumentNullException>(() => new TestObject().AssertPropertyInvalid(null));
        }

        [Fact]
        public void AssertPropertyInvalidShouldThrowIfPropertyHasNoErrorsWhenNull()
        {
            Assert.Throws<AssertFailedException>(() => new TestObject().AssertPropertyInvalid(o => o.ValidPropertyNull));
        }

        [Fact]
        public void AssertPropertyInvalidShouldThrowIfPropertyHasNoErrorsWhenBlank()
        {
            Assert.Throws<AssertFailedException>(() => new TestObject().AssertPropertyInvalid(o => o.ValidPropertyBlank));
        }

        [Fact]
        public void AssertPropertyInvalidShouldNotThrowIfPropertyHasErrors()
        {
            Assert.DoesNotThrow(() => new TestObject().AssertPropertyInvalid(o => o.InvalidProperty));
        }

        private class TestObject : IDataErrorInfo
        {
            public object InvalidProperty { get; set; }
            public object ValidPropertyNull { get; set; }
            public object ValidPropertyBlank { get; set; }

            public string Error
            {
                get { throw new NotImplementedException(); }
            }

            public string this[string columnName]
            {
                get 
                {
                    if(columnName == "InvalidProperty")
                    {
                        return "Error Message";
                    }
                    else if(columnName == "ValidPropertyBlank")
                    {
                        return string.Empty;
                    }
                    return null;
                }
            }
        }
    }
}
